﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Globalization;

using System.Diagnostics;
using System.Reflection;

using NHunspell;

namespace System.Windows.KExtensions {

    /// <summary>
    ///  A control to view or edit styled text
    /// </summary>
    public static class SpellCheck {

        public static string DefaultDicPath { get; set; }

        public static string DefaultLanguage { get; set; }

        public static bool DisableAll { get; set; }

      
        internal static Hunspell GetHunspell(string language) {

            if (language == null) {
                language = DefaultLanguage;

                if (DefaultLanguage == null)
                    language = System.Globalization.CultureInfo.CurrentCulture.Name;
            }

            string path = DefaultDicPath + language.Replace("-", "_");
            Hunspell h = null;
            try {
                h = new Hunspell(path + ".aff", path + ".dic");
            } catch (Exception) {
                System.Console.Out.WriteLine("Fail to open dictionary files at: " + path);
            }
            return h;
        }

        public static readonly DependencyProperty XOffsetProperty =
                DependencyProperty.RegisterAttached("XOffset", typeof(double), typeof(SpellCheck), new UIPropertyMetadata(0.0));

        public static readonly DependencyProperty YOffsetProperty =
                DependencyProperty.RegisterAttached("YOffset", typeof(double), typeof(SpellCheck), new UIPropertyMetadata(0.0));

        public static double GetXOffset(DependencyObject obj) {
            return (double)obj.GetValue(XOffsetProperty);
        }

        public static void SetXOffset(DependencyObject obj, double value) {
            obj.SetValue(XOffsetProperty, value);
        }

        public static double GetYOffset(DependencyObject obj) {
            return (double)obj.GetValue(YOffsetProperty);
        }

        public static void SetYOffset(DependencyObject obj, double value) {
            obj.SetValue(YOffsetProperty, value);
        }

        public static string GetDictionaryWasNotFound(DependencyObject obj) {
            return (string)obj.GetValue(DictionaryWasNotFoundProperty);
        }

        public static readonly DependencyProperty DictionaryWasNotFoundProperty =
                DependencyProperty.RegisterAttached("DictionaryWasNotFound", typeof(bool), typeof(SpellCheck), new UIPropertyMetadata(false));

        public static string GetLanguage(DependencyObject obj) {
            return (string)obj.GetValue(LanguageProperty);
        }

        public static void SetLanguage(DependencyObject obj, string value) {
            obj.SetValue(LanguageProperty, value);
        }

        public static readonly DependencyProperty LanguageProperty =
                DependencyProperty.RegisterAttached("Language", typeof(string), typeof(SpellCheck), new UIPropertyMetadata(null));

        public static bool GetIsEnabled(DependencyObject obj) {
            return (bool)obj.GetValue(IsEnabledProperty);
        }

        public static void SetIsEnabled(DependencyObject obj, bool value) {
            obj.SetValue(IsEnabledProperty, value);
        }

        public static readonly DependencyProperty IsEnabledProperty =
                DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(SpellCheck), new UIPropertyMetadata(false, OnIsEnabledChanged));

        private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {

            bool enabled = (bool)e.NewValue;
            if (!enabled)
                return;
            
            var uie = GetTextBox(d);

            uie.Loaded -= new RoutedEventHandler(uie_Loaded);
            if(enabled)
                uie.Loaded += new RoutedEventHandler(uie_Loaded);

           
        }

   
   
        /// <summary>
        /// Create adorner when control is loaded.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void uie_Loaded(object sender, RoutedEventArgs e) {
            var uie = GetTextBox(sender);




            AdornerLayer layer = AdornerLayer.GetAdornerLayer(uie);

            if (layer == null)
                return;

            Adorner[] adorners = layer.GetAdorners(uie);
            if (adorners!=null && adorners.Count(a => a is System.Windows.KExtensions.Adorners.SpellerAdorner) > 0)
                return;

            System.Windows.KExtensions.Adorners.SpellerAdorner spAd = new System.Windows.KExtensions.Adorners.SpellerAdorner(uie);
            
            layer.Add(spAd);
        }

        private static TextBox GetTextBox(object d) {
            var uie = d as TextBox;
            if (d == null)
                throw new Exception("SpellCheckExtension can only be used at TextBox controls");
            return uie;
        }



    }
}

